var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //物联网平台Topic，设备上传属性数据到云端。
var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //物联网平台Topic，云端下发属性控制指令到设备端。
var ALINK_PROP_SET_REPLY_METHOD = 'thing.service.property.set'; //物联网平台Topic，设备上报属性设置的结果到云端。


/* up data,  device->cloud*/
var ALI_MODEL_PROP_REPORT=0x00;
var ALI_MODEL_EVENT_REPORT=0x01; 
/* up data , cloud->device*/
var ALI_MODEL_PROP_REPORT_REPLY=0x02;
var ALI_MODEL_EVENT_REPORT_REPLY=0x03; 
/* down data, cloud->device*/
var ALI_MODEL_PROP_SET=0x04;
var ALI_MODEL_SERVICE_SET=0x05;
/* down data, device->cloud */
var ALI_MODEL_PROP_SET_REPLY=0x06;
var ALI_MODEL_SERVICE_REPLY=0x07;
/* other*/
var ALI_MODEL_UNKOWN=0XFF;


var PARAM_ONLINE=0X10;
var PARAM_ONLINE01=0X11;
var PARAM_ONLINE02=0X12;
var PARAM_ONLINE03=0X13;
var PARAM_ONLINE04=0X14;
var PARAM_ONLINE05=0X15;

var PARAM_ALARM=0X20;
var PARAM_ALARM01=0X21;
var PARAM_ALARM02=0X22;
var PARAM_ALARM03=0X23;
var PARAM_ALARM04=0X24;
var PARAM_ALARM05=0X25;


var PARAM_BAT=0X30;
var PARAM_BAT01=0X31;
var PARAM_BAT02=0X32;
var PARAM_BAT03=0X33;
var PARAM_BAT04=0X34;
var PARAM_BAT05=0X35;

var PARAM_ALARM_SWITCH=0X40;

/*
示例数据：
设备上报属性数据：
传入参数：
    0x000000000100320100000000
输出结果：
    {"method":"thing.event.property.post","id":"1","params":{"prop_float":0,"prop_int16":50,"prop_bool":1},"version":"1.0"}

属性设置的返回结果：
传入参数：
    0x0300223344c8
输出结果：
    {"code":"200","data":{},"id":"2241348","version":"1.0"}
*/
function rawDataToProtocol(bytes) {
    var uint8Array = new Uint8Array(bytes.length);
    for (var i = 0; i < bytes.length; i++) {
        uint8Array[i] = bytes[i] & 0xff;
    }
    var dataView = new DataView(uint8Array.buffer, 0);
    var jsonMap = new Object();
    var fHead = uint8Array[0]; // command
    if (fHead == ALI_MODEL_PROP_REPORT) {
        jsonMap['method'] = ALINK_PROP_REPORT_METHOD; //ALink JSON格式，属性上报topic。
        jsonMap['version'] = '1.0'; //ALink JSON格式，协议版本号固定字段。
        jsonMap['id'] = '' + dataView.getInt32(1,true); //ALink JSON格式，标示该次请求id值。
        var params = {};
        var param_type=uint8Array[5];
        
        if((param_type&0xf0)==PARAM_ALARM)
        {
            switch (param_type)
            {
                case PARAM_ALARM01:
                    params['alarm01']=uint8Array[6];
                    break;
                case PARAM_ALARM02:
                    params['alarm02']=uint8Array[6];
                    break;
                case PARAM_ALARM03:
                    params['alarm03']=uint8Array[6];
                    break;
                case PARAM_ALARM04:
                    params['alarm04']=uint8Array[6];
                    break;
                case PARAM_ALARM05:
                    params['alarm05']=uint8Array[6];
                    break;
            }
        }
        else if((param_type&0xf0)==PARAM_ONLINE)
        {
            switch (param_type)
            {
                case PARAM_ONLINE01:
                    params['bat01']=uint8Array[6];
                    break;
                case PARAM_ONLINE02:
                    params['bat02']=uint8Array[6];
                    break;
                case PARAM_ONLINE03:
                    params['bat03']=uint8Array[6];
                    break;
                case PARAM_ONLINE04:
                    params['bat04']=uint8Array[6];
                    break;
                case PARAM_ONLINE05:
                    params['bat05']=uint8Array[6];
                    break;
            }
        }
        else if((param_type&0xf0)==PARAM_BAT)
        {
            switch (param_type)
            {
                case PARAM_BAT01:
                    params['bat01']=uint8Array[6];
                    break;
                case PARAM_BAT02:
                    params['bat02']=uint8Array[6];
                    break;
                case PARAM_BAT03:
                    params['bat03']=uint8Array[6];
                    break;
                case PARAM_BAT04:
                    params['bat04']=uint8Array[6];
                    break;
                case PARAM_BAT05:
                    params['bat05']=uint8Array[6];
                    break;
            }
        }
        
        jsonMap['params'] = params; //ALink JSON格式，params标准字段。
    } else if(fHead == ALI_MODEL_PROP_SET_REPLY) {
        jsonMap['version'] = '1.0'; //ALink JSON格式，协议版本号固定字段。
        jsonMap['id'] = '' + dataView.getInt32(1,true); //ALink JSON格式，标示该次请求id值。
        jsonMap['code'] = ''+ dataView.getUint8(5);
        jsonMap['data'] = {};
    }

    return jsonMap;
}
/*
示例数据：
云端下发属性设置指令：
传入参数：
    {"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}
输出结果：
    0x0100003039014d0142f6e76d

设备上报的返回结果：
传入数据：
    {"method":"thing.event.property.post","id":"12345","version":"1.0","code":200,"data":{}}
输出结果：
    0x0200003039c8
*/
function protocolToRawData(json) {
    var method = json['method'];
    var id = json['id'];
    var version = json['version'];
    var payloadArray = [];
    if (method == ALINK_PROP_SET_METHOD) //属性设置。
    {
        var params = json['params'];
        
        payloadArray = payloadArray.concat(buffer_uint8(ALI_MODEL_PROP_SET));
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id)));
        if('AlarmSwitch' in params)
        {
            payloadArray = payloadArray.concat(buffer_uint8(PARAM_ALARM_SWITCH));
            payloadArray = payloadArray.concat(buffer_uint8(params['AlarmSwitch']));
        }
    } else if (method ==  ALINK_PROP_REPORT_METHOD) { //设备上报数据返回结果。
        var code = json['code'];
        payloadArray = payloadArray.concat(buffer_uint8(ALI_MODEL_PROP_REPORT_REPLY)); //command字段。
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
        payloadArray = payloadArray.concat(buffer_uint8(code));
    } else { //未知命令，对于这些命令不做处理。
        var code = json['code'];
        payloadArray = payloadArray.concat(buffer_uint8(ALI_MODEL_UNKOWN)); //command字段。
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
        payloadArray = payloadArray.concat(buffer_uint8(code));
    }
    return payloadArray;
}


function transformPayload(topic, bytes) {
    var jsonMap = {};
    return jsonMap;
}

//以下是部分辅助函数。
function buffer_uint8(value) {
    var uint8Array = new Uint8Array(1);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setUint8(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int16(value) {
    var uint8Array = new Uint8Array(2);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt16(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int32(value) {
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt32(0, value);
    return [].slice.call(uint8Array);
}
function buffer_float32(value) {
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setFloat32(0, value);
    return [].slice.call(uint8Array);
}